﻿// <copyright file="MainWindow.xaml.cs" company="Soumya Chattopadhyay">
// Copyright (c) 2010 All Right Reserved
// </copyright>
// <disclaimer> This software is intented for educational purposes only and not for 
// commerical or prodution use. The software is provided "as is", without warranty 
// of any kind, express or implied, including but not limited to the warranties of 
// merchantability, fitness for a particular purpose and noninfringement. In no event 
// shall the author(s) or copyright holder(s) be liable for any claim, damages or other 
// liability, whether in an action of contract, tort or otherwise, arising from, out of 
// or in connection with the software or the use or other dealings in the software.
// </disclaimer>

namespace My.CodePlex.TFSExplorer
{
    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using Microsoft.TeamFoundation.Client;
    using Microsoft.TeamFoundation.Proxy;
    using Microsoft.TeamFoundation.VersionControl.Client;
    using Microsoft.TeamFoundation.VersionControl.Common;
    using My.CodePlex.TFSExplorer.Controls;
    using My.CodePlex.TFSExplorer.Resources;
    using My.CodePlex.TFSExplorer.TeamFoundation;

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Fields

        /// <summary>
        /// Populate the child controls thread
        /// </summary>
        private Thread populateControlsThread;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the MainWindow class
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            // Display the child controls
            this.DisplayCholdControls();

            this.WaitCursor.Stop();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the TFS context
        /// </summary>
        public TeamFoundationContext TeamFoundationContext { get; set; }

        #endregion

        #region Menu handlers

        /// <summary>
        /// When the connect to TFS server is called
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void OpenTFSServerMenuItemClick(object sender, RoutedEventArgs e)
        {
            ServerConnect serverConnect = new ServerConnect();
            serverConnect.OnPopulateStart += this.ServerConnectOnPopulateStart;
            serverConnect.OnPopulateEnd += this.ServerConnectOnPopulateEnd;
            serverConnect.Connect(this.Dispatcher);
        }

        /// <summary>
        /// Handle the OnPopulationStart event from the ServerConnect control
        /// </summary>
        /// <param name="obj">The server name</param>
        private void ServerConnectOnPopulateStart(object obj)
        {
            string serverName = obj as string;
            this.WaitCursor.Start();
        }

        /// <summary>
        /// Close the main window
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void ExitMenuItemClick(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Set focus to the pending changes view tab
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void PendingChangesViewMenuItemClick(object sender, RoutedEventArgs e)
        {
            if (!this.PendingChangesTabItem.IsFocused)
            {
                this.PendingChangesTabItem.Focus();
            }
        }

        /// <summary>
        /// Set focus to the shelve set view tab
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void ShelveSetViewMenuItemClick(object sender, RoutedEventArgs e)
        {
            if (!this.ShelvesetTabItem.IsFocused)
            {
                this.ShelvesetTabItem.Focus();
            }
        }

        /// <summary>
        /// Set focus to the source code tree view tab
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void SourceCodeViewMenuItemClick(object sender, RoutedEventArgs e)
        {
            if (!this.SourceTreeTabItem.IsFocused)
            {
                this.SourceTreeTabItem.Focus();
            }
        }

        /// <summary>
        /// Set focus to the server details
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void ServerDetailsViewMenuItemClick(object sender, RoutedEventArgs e)
        {
            if (!this.ServerDetailsTabItem.IsFocused)
            {
                this.ServerDetailsTabItem.Focus();
            }
        }

        /// <summary>
        /// Set focus to the user's tab
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void UsersViewMenuItemClick(object sender, RoutedEventArgs e)
        {
            if (!this.UsersTabItem.IsFocused)
            {
                this.UsersTabItem.Focus();
            }
        }

        /// <summary>
        /// Go to the help page
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void AboutMenuItemClick(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start(Resource.MyWebPage);
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Display the child controls
        /// </summary>
        private void DisplayCholdControls()
        {
            // Hook up listeners
            this.Users.OnDisplayUserChanged += this.UsersOnDisplayUserChanged;
            this.SourceTreeControl.ViewDetails += new Action<UserControl>(this.SourceTreeControl_ViewDetails);
        }

        /// <summary>
        /// When connected to the server start populating the controls
        /// </summary>
        /// <param name="obj">The TFS server context</param>
        private void ServerConnectOnPopulateEnd(object obj)
        {
            // Check for success or failure
            if (obj != null)
            {
                // Was there an error?
                string errorMsg = obj as string;
                if (errorMsg != null)
                {
                    this.WindowStatus.Text = Resource.VSErrorNotMapped;
                    this.WaitCursor.Stop();

                    return;
                }

                // There was no error
                this.WindowStatus.Text = string.Empty;
                this.TeamFoundationContext = obj as TeamFoundationContext;

                this.ShelvesetTabItem.Header = string.Format(Resource.ShelvesetTabItemHeader, TeamFoundationContext.CurrentDisplayUser.ToLower());
                this.PendingChangesTabItem.Header = string.Format(Resource.PendingChangesTabItemHeader, TeamFoundationContext.CurrentDisplayUser.ToLower());

                this.WaitCursor.Stop();
                this.containerTabControl.Visibility = Visibility.Visible;
                this.ViewMenuItem.IsEnabled = true;

                this.populateControlsThread = new Thread(this.PopulateControls);
                this.populateControlsThread.SetApartmentState(ApartmentState.STA);
                this.populateControlsThread.Start(TeamFoundationContext.CurrentProject.ServerItem);
            }
            else
            {
                this.WaitCursor.Stop();
            }
        }

        /// <summary>
        /// Populate all the child controls
        /// </summary>
        /// <param name="data">This parameter is not used.</param>
        private void PopulateControls(object data)
        {
            this.SourceTreeControl.Populate(this.TeamFoundationContext);
            this.ShelveControl.Populate(this.TeamFoundationContext);
            this.PendingChanges.Populate(this.TeamFoundationContext);
            this.Users.Populate(this.TeamFoundationContext);
            this.ServerDetails.Populate(this.TeamFoundationContext);
        }

        /// <summary>
        /// If the display user's changed , we'll update the shelveset and pending changes views
        /// </summary>
        /// <param name="userName">The current display user</param>
        private void UsersOnDisplayUserChanged(string userName)
        {
            this.ShelvesetTabItem.Header = string.Format(Resource.ShelvesetTabItemHeader, TeamFoundationContext.CurrentDisplayUser);
            this.PendingChangesTabItem.Header = string.Format(Resource.PendingChangesTabItemHeader, TeamFoundationContext.CurrentDisplayUser);

            this.ShelveControl.Populate(this.TeamFoundationContext);
            this.PendingChanges.Populate(this.TeamFoundationContext);
        }

        /// <summary>
        /// View the details of the change set
        /// </summary>
        /// <param name="obj">The user control to display</param>
        private void SourceTreeControl_ViewDetails(UserControl obj)
        {
            CloseableTabItem tabItem = new CloseableTabItem();
            this.AddHandler(CloseableTabItem.CloseTabEvent, new RoutedEventHandler(this.CloseTab));
            ChangeSetDetailsControl cs = obj as ChangeSetDetailsControl;
            tabItem.Header = cs.Tag as string;
            tabItem.Content = cs;

            this.containerTabControl.Items.Add(tabItem);
        }

        /// <summary>
        /// Handle the close tab routed event and close the tab item
        /// </summary>
        /// <param name="source">The source tab item</param>
        /// <param name="args">The routed event arguments</param>
        private void CloseTab(object source, RoutedEventArgs args)
        {
            TabItem tabItem = args.Source as TabItem;
            if (tabItem != null)
            {
                TabControl tabControl = tabItem.Parent as TabControl;
                if (tabControl != null)
                {
                    tabControl.Items.Remove(tabItem);
                }
            }
        }

        #endregion
    }
}
